package com.efeichong.lock;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author lxk
 * @date 2020/02/04
 * @description 对指定方法进行上锁, 可指定线程锁还是分布式锁 {@link #lockType()}
 * 1.解决并发问题
 * 2.可通过表达式定义key实现防重复提交
 * 使用
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface Lock {
    /**
     * 锁自动过期时长(大于0设置时间有效，小于等于0则为永不过期),过期自动释放,默认永不过期 单位：毫秒
     */
    public static final long LOCK_EXPIRE_TIME = 0;
    /**
     * 重试次数  默认不重试
     */
    public static final int RETRY_COUNT = 0;
    /**
     * 重试时间间隔 单位：毫秒
     */
    public static final int RETRY_TIME_INTERVAL = 10;

    /**
     * 锁的唯一标识 支持表达式
     * 写法1. theKey
     * 写法2. ${com.test.MyConcatUtils.concat()} 这种写法要求
     * 1.以${}做包裹
     * 2.包路径必须正确,类必须为public修饰
     * 3.方法必须是静态方法且为public修饰
     * 4.该静态方法内如需用到spring装配请使用 {@link SpringUtils#getBean(String)}
     *
     * @return
     */
    String key();

    /**
     * 锁类型  默认使用 线程重入锁 {@link LockType}
     *
     * @return
     */
    LockType lockType() default LockType.THREAD_LOCK;

    /**
     * 锁自动过期时长(大于0设置时间有效，小于等于0则为永不过期),过期自动释放,默认永不过期 单位：毫秒
     *
     * @return
     */
    long lockExpireTime() default LOCK_EXPIRE_TIME;

    /**
     * 自动重试次数,默认不重试
     *
     * @return
     */
    int retryCount() default RETRY_COUNT;

    /**
     * 重试时间间隔,默认10毫秒,与重试次数配合使用 单位：毫秒
     *
     * @return
     */
    long retryTimeInterval() default RETRY_TIME_INTERVAL;
}
